#ifndef __MVDEF_H__
#define __MVDEF_H__

///
///<summary>
///Macro-Video Various Common Defines
///</summary>
///<version V4.0 />
///

/* Common headers */

#ifndef __cplusplus
#define MVCXX_EXTERN_BEGIN
#define MVCXX_EXTERN_END
#define MVC_EXTERN               extern
#else
#define MVCXX_EXTERN_BEGIN       extern "C" {
#define MVCXX_EXTERN_END         }
#define MVC_EXTERN
#endif

MVCXX_EXTERN_BEGIN

/*************************************
     APIs prefix of symbol attr
*************************************/
// Generic helper definitions for shared library support
#if defined _WIN32 || defined __CYGWIN__
  #define MVDLS_DLL_IMPORT __declspec(dllimport)
  #define MVDLS_DLL_EXPORT __declspec(dllexport)
  #define MVDLS_DLL_LOCAL
#else
  #if __GNUC__ >= 4
    #define MVDLS_DLL_IMPORT __attribute__ ((visibility ("default")))
    #define MVDLS_DLL_EXPORT __attribute__ ((visibility ("default")))
    #define MVDLS_DLL_LOCAL  __attribute__ ((visibility ("hidden")))
  #else
    #define MVDLS_DLL_IMPORT
    #define MVDLS_DLL_EXPORT
    #define MVDLS_DLL_LOCAL
  #endif
#endif

// Now we use the generic helper definitions above to define MVAPI and MVLOCAL.
// MVAPI is used for the public API symbols. It either DLL imports or DLL exports (or does nothing for static build)
// MVLOCAL is used for non-api symbols.

#ifdef MVDLS // defined if module is compiled as a DLL Service
  #ifdef MV_DLL_EXPORTS // defined if we are building the MV DLL (instead of using it)
    #define MVAPI MVDLS_DLL_EXPORT
  #else
    #define MVAPI MVDLS_DLL_IMPORT
  #endif // MV_DLL_EXPORTS
  #define MVLOCAL MVDLS_DLL_LOCAL
#else // MVDLS is not defined: this means module is a static lib.
  #define MVAPI
  #define MVLOCAL
#endif // MVDLS

// 计算 __VA_ARGS__ 参数个数,最大支持64个参数
#define MV_ARG_COUNT(...) MV_INTERNAL_ARG_COUNT_PRIVATE(0, ##__VA_ARGS__,\
	64, 63, 62, 61, 60, \
	59, 58, 57, 56, 55, 54, 53, 52, 51, 50, \
	49, 48, 47, 46, 45, 44, 43, 42, 41, 40, \
	39, 38, 37, 36, 35, 34, 33, 32, 31, 30, \
	29, 28, 27, 26, 25, 24, 23, 22, 21, 20, \
	19, 18, 17, 16, 15, 14, 13, 12, 11, 10, \
	 9,  8,  7,  6,  5,  4,  3,  2,  1,  0)
#define MV_INTERNAL_ARG_COUNT_PRIVATE(\
	 _0,  _1,  _2,  _3,  _4,  _5,  _6,  _7,  _8,  _9, \
	_10, _11, _12, _13, _14, _15, _16, _17, _18, _19, \
	_20, _21, _22, _23, _24, _25, _26, _27, _28, _29, \
	_30, _31, _32, _33, _34, _35, _36, _37, _38, _39, \
	_40, _41, _42, _43, _44, _45, _46, _47, _48, _49, \
	_50, _51, _52, _53, _54, _55, _56, _57, _58, _59, \
	_60, _61, _62, _63, _64, N, ...) N
/*************************************
     various common type defines
*************************************/

typedef void                      mv_void_t;
typedef char                      mv_v8_t; //special for "char" variable with compiler for some functions
typedef unsigned char             mv_u8_t;
typedef signed char               mv_s8_t;
typedef unsigned short int        mv_u16_t;
typedef signed short int          mv_s16_t;
typedef unsigned int              mv_u32_t;
typedef signed int                mv_s32_t;
typedef unsigned long long        mv_u64_t;
typedef signed long long          mv_s64_t;
typedef float                     mv_f32_t;
typedef double                    mv_f64_t;

typedef const char                mv_cv8_t; //special for "char" variable with compiler for some functions
typedef const unsigned char       mv_cu8_t;
typedef const signed char         mv_cs8_t;
typedef const unsigned short int  mv_cu16_t;
typedef const signed short int    mv_cs16_t;
typedef const unsigned int        mv_cu32_t;
typedef const signed int          mv_cs32_t;
typedef const unsigned long long  mv_cu64_t;
typedef const signed long long    mv_cs64_t;
typedef const float               mv_cf32_t;
typedef const double              mv_cf64_t;

typedef void*                     mv_vptr_t;
typedef char*                     mv_v8ptr_t; //special for "char" variable with compiler for some functions
typedef unsigned char*            mv_u8ptr_t;
typedef signed char*              mv_s8ptr_t;
typedef unsigned short int*       mv_u16ptr_t;
typedef signed short int*         mv_s16ptr_t;
typedef unsigned int*             mv_u32ptr_t;
typedef signed int*               mv_s32ptr_t;
typedef unsigned long long*       mv_u64ptr_t;
typedef signed long long*         mv_s64ptr_t;
typedef float*                    mv_f32ptr_t;
typedef double*                   mv_f64ptr_t;

typedef const void*               mv_cvptr_t;
typedef const char*               mv_cv8ptr_t; //special for "char" variable with compiler for some functions
typedef const unsigned char*      mv_cu8ptr_t;
typedef const signed char*        mv_cs8ptr_t;
typedef const unsigned short int* mv_cu16ptr_t;
typedef const signed short int*   mv_cs16ptr_t;
typedef const unsigned int*       mv_cu32ptr_t;
typedef const signed int*         mv_cs32ptr_t;
typedef const unsigned long long* mv_cu64ptr_t;
typedef const signed long long*   mv_cs64ptr_t;
typedef const float*              mv_cf32ptr_t;
typedef const double*             mv_cf64ptr_t;

typedef unsigned char             mv_bool_t;
typedef unsigned long long        mv_size_t;
typedef long long                 mv_ssize_t;
typedef long long                 mv_off_t;
typedef long long                 mv_time_t;

typedef long                      mv_intptr_t;  ///< 指针类型强转有符号数值使用
typedef unsigned long             mv_uintptr_t; ///< 指针类型强转无符号数值使用
#define sign2vptr(sign_value)     ((mv_vptr_t)(mv_intptr_t)(sign_value))  ///< 有符号数值强转指针类型（注意：使用时必须知道自己在做什么）
#define unsign2vptr(sign_value)   ((mv_vptr_t)(mv_uintptr_t)(sign_value)) ///< 无符号数值强转指针类型（注意：使用时必须知道自己在做什么）
#define ptr2value(ptr, T)         ((T)(mv_uintptr_t)(ptr))                ///< 指针类型强转指定数值类型（注意：使用时必须知道自己在做什么）

#define MV_TRUE                   (1==1)
#define MV_FALSE                  (0==1)

#ifndef NULL
#ifdef __GNUG__
#define NULL __null
#else   /* G++ */
#ifndef __cplusplus
#define NULL ((void *)0)
#else   /* C++ */
#define NULL 0
#endif  /* C++ */
#endif  /* G++ */
#endif

#define mv_sizeof_member(type,mem)   sizeof(((type*)0)->mem)

/** 对齐规范设计，结构体末尾包含变长数组用于强转其他类型结构体时，使用此设计规范可以避免非对齐地址强转问题 */
#if __WORDSIZE == 64
#define sz_valign 8
#else
#define sz_valign 4
#endif
#define valign_addr(addr)    (((unsigned long)addr + sz_valign - 1) & ~(sz_valign - 1))

/** 标准错误码集 */
typedef enum _mv_error_code
{
    MV_EC_SUCCESS            =   0,
    MV_EC_FAILED             =  -1,
    MV_EC_ABORT              =  -2,
    MV_EC_RETRY              =  -3,
    MV_EC_IGNORE             =  -4,
    
    MV_EC_NOT_INIT           =  -10, ///< mostly shows that the function/module was not inited
    MV_EC_INVALID_ARGS       =  -11, ///< some of input arguments is illegal or invalid
    MV_EC_REDEF              =  -12, ///< some init/defined is init/define again
    MV_EC_MALLOC_FAILED      =  -13, ///< malloc/alloc/realloc failed
    MV_EC_RESOURCE_LEAK      =  -14, ///< some predistribution resource is not enough for this request action
    MV_EC_NOT_FOUND          =  -15, ///< target not found in request action
    MV_EC_TIMEOUT            =  -16, ///< timeout
    MV_EC_CONNECT_ERROR      =  -17, ///< mostly is connect to target server failed
    MV_EC_RSP_ERROR          =  -18, ///< mostly is the server response not expected
    MV_EC_VERIFY_FAILED      =  -19, ///< failed of any verify method
    MV_EC_ACTION_BUSY        =  -20, ///< mostly is busy calling by multi-caller or in some unchangeable status that call comes failed
    MV_EC_OUT_OF_RANGE       =  -21, ///< mostly is a num out of the specified range
    MV_EC_NOT_MATCH          =  -22, ///< mostly is comparison failed
    MV_EC_GET_HOST_FAILED    =  -23, ///< host ip analyze failed
    MV_EC_SOCKET_ERROR       =  -24, ///< socket create failed
    MV_EC_NOT_READY          =  -25, ///< mostly is a status check result shown that some action is not ready yet
    MV_EC_IO_ERROR           =  -26, ///< mostly is file input/output ctrl error
    MV_EC_NOT_SUPPORT        =  -27, ///< mostly is function/api is not available when compiling or hardware adaption
    MV_EC_READ_ONLY          =  -28, ///< do write control at readonly item/situration
    MV_EC_PERMS_DENIED       =  -29, ///< mostly some action or calling withless permission
    MV_EC_EOF                =  -30, ///< end of file or string or something else
    MV_EC_UNREACHABLE        =  -31, ///< mostly is a message can't arrive target
    MV_EC_FATAL_ERROR        =  -32, ///< mostly is something always error occured and can't recover
}mvdef_ec_e;

MVCXX_EXTERN_END

#endif
